/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package obai.control;

import com.sun.rave.web.ui.appbase.AbstractRequestBean;
import obai.ApplicationBean1;
import obai.model.util.PathParser;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import javax.faces.FacesException;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

/**
 * <p>Request scope data bean for your application.  Create properties
 *  here to represent data that should be made available across different
 *  pages in the same HTTP request, so that the page bean classes do not
 *  have to be directly linked to each other.</p>
 *
 * <p>An instance of this class will be created for you automatically,
 * the first time your application evaluates a value binding expression
 * or method binding expression that references a managed bean using
 * this class.</p>
 *
 * @version ResourceFinder.java
 * @version Created on Jan 19, 2009, 10:10:19 PM
 * @author Fernando Arena Varella
 */

public class ResourceFinder extends AbstractRequestBean {
    // <editor-fold defaultstate="collapsed" desc="Managed Component Definition">

    /**
     * <p>Automatically managed component initialization.  <strong>WARNING:</strong>
     * This method is automatically generated, so any user-specified code inserted
     * here is subject to being replaced.</p>
     */
    private void _init() throws Exception {
    }
    // </editor-fold>

    /**
     * <p>Construct a new request data bean instance.</p>
     */
    public ResourceFinder() {
    }

    /**
     * <p>This method is called when this bean is initially added to
     * request scope.  Typically, this occurs as a result of evaluating
     * a value binding or method binding expression, which utilizes the
     * managed bean facility to instantiate this bean and store it into
     * request scope.</p>
     *
     * <p>You may customize this method to allocate resources that are required
     * for the lifetime of the current request.</p>
     */
    @Override
    public void init() {
        // Perform initializations inherited from our superclass
        super.init();
        // Perform application initialization that must complete
        // *before* managed components are initialized
        // TODO - add your own initialiation code here

        // <editor-fold defaultstate="collapsed" desc="Managed Component Initialization">
        // Initialize automatically managed components
        // *Note* - this logic should NOT be modified
        try {
            _init();
        } catch (Exception e) {
            log("ResourceFinder Initialization Failure", e);
            throw e instanceof FacesException ? (FacesException) e: new FacesException(e);
        }

        // </editor-fold>
        // Perform application initialization that must complete
        // *after* managed components are initialized
        // TODO - add your own initialization code here
    }

    /**
     * <p>This method is called when this bean is removed from
     * request scope.  This occurs automatically when the corresponding
     * HTTP response has been completed and sent to the client.</p>
     *
     * <p>You may customize this method to clean up resources allocated
     * during the execution of the <code>init()</code> method, or
     * at any later time during the lifetime of the request.</p>
     */
    @Override
    public void destroy() {
    }


//    private HtmlOutputText resourcePath;
    //It is an ArrayList because we can't bind 2 components on the same property
    private ArrayList<HtmlOutputText> resourcePath = new ArrayList<HtmlOutputText>();
    private int writtenCount=0, readCount=0;



    /**
     * Build the String of the path of a resource. The output will be the
     * built based on the default resource path and the target plataform
     * @return  the String of the path
     */
    public String getMakeResourcePath() {
        String defaultPath = (String) resourcePath.get(readCount++).getAttributes().get("path");

        PlataformBean.Plataform plataform = getPlataformBean().getPlataform();
        String recPath = "";
        System.out.println("Plataform.toString = " + plataform.toString());
//        if (plataform != PlataformBean.Plataform.WEB)
            recPath = buildResourcePath(defaultPath, plataform.toString());

        System.out.println("DefaultPath[" + (readCount-1) + "] = " + defaultPath);
        System.out.println("Built Path: " + recPath);
//        System.out.println("/Interop/faces" + recPath);
        return recPath;
    }


    public String makeFinalReference(String originalSrc){
        System.out.println("Original Src: " + originalSrc);

        PlataformBean.Plataform plataform = getPlataformBean().getPlataform();
        String finalSrc = "";
        finalSrc = buildResourcePath(originalSrc, plataform.toString());

        System.out.println("Final Src: " + finalSrc);
        return finalSrc;
    }

    /**
     * Build the String of the path to a resource.
     * TODO: arrumar a função para funcionar corretamente quando o caminho
     * original começa por "../"
     * @param original  the original path of the resource
     * @param plataform the target plataform
     * @return  the path to the same resource but under the target plataform
     * directories tree
     */
    private String buildResourcePath(String original, String plataform){
        ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();
        String alternativeResource = PathParser.concatenateStringToFileName(original, plataform);

        String altResourcePath = PathParser.excludeFileName(ctx.getRequestPathInfo());
        String relativePath = plataform + "/" + original;
        altResourcePath += alternativeResource;
        //fix all the "../" ignoring the plataform String
        altResourcePath = PathParser.fixBackwardsDirectories(altResourcePath, plataform);

//        System.out.println("altResourcePath: " + altResourcePath);

        if (resourceExists(altResourcePath))
            return alternativeResource;
        else
            return original;
    }

    /**
     * Test if the given resource exists in the server
     * @param path  the path to the resource
     * @return  true if it exists, false otherwise
     */
    private boolean resourceExists(String path){
        ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();
        Set<String> paths = ctx.getResourcePaths(PathParser.excludeFileName(path));
//        for (String s : paths){
//            System.out.println("Resource Path: " + s);
//        }
        if (paths == null)
            paths = new HashSet<String>();

        if (paths.contains(path))
            return true;

//        HttpServletRequest request = (HttpServletRequest)
//                FacesContext.getCurrentInstance().getExternalContext().getRequest();
//        System.out.println("ctx.getRequestServletPath(): " + ctx.getRequestServletPath());
//        System.out.println("ctx.getRequestPathInfo(): " + ctx.getRequestPathInfo());
//        System.out.println("ctx.getRequestContextPath(): " + ctx.getRequestContextPath());

        return false;
    }


    public synchronized HtmlOutputText getResourcePath() {
//        resourcePath.add(writtenCount, new HtmlOutputText());
        //it's a trick to bind multiple components on this same property
        resourcePath.add(new HtmlOutputText());
        return resourcePath.get(writtenCount++);
    }

    public synchronized void setResourcePath(HtmlOutputText resourcePath) {
        System.out.println("SETTING RESOURCE PATH");
        this.resourcePath.set(writtenCount, resourcePath);
    }

    protected ApplicationBean1 getApplicationBean1() {
        return (ApplicationBean1) getBean("ApplicationBean1");
    }
    protected PlataformBean getPlataformBean() {
        return (PlataformBean) getBean("control$PlataformBean");
    }

}
